package example.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import io.jsonwebtoken.Clock;
import io.jsonwebtoken.impl.DefaultClock;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;

/**
 * TODO
 * 中农裕坤 JWT 生成 和 解析 和 验证
 *
 * <dependency>
 * <groupId>io.jsonwebtoken</groupId>
 * <artifactId>jjwt</artifactId>
 * <version>0.9.1</version>
 * </dependency>
 *
 * <dependency>
 * <groupId>com.auth0</groupId>
 * <artifactId>java-jwt</artifactId>
 * <version>3.9.0</version>
 * </dependency>
 *
 * @author zgq
 * @date 2020/10/22 10:55
 */
@Slf4j
@Component
public class Jwt_Auth0_JWTUtil {
    /**
     * 盐
     */
    private final String secret = "zhang";
    /**
     * 失效时间 2 小时
     */
    private final Long expire = 72000000L;
    /**
     * 时钟
     */
    Clock clock = DefaultClock.INSTANCE;

    /**
     * 生成 Token
     *
     * @param claims    自定义要求规范
     * @param loginName 登录名称
     * @return token
     */
    public String generateToken(Map<String, Object> claims, String loginName) {
        String token = JWT.create()
                // 登录人的 ID
                .withJWTId("1001")
                // 设置登陆人
                .withSubject(loginName)
                // 设置 Token 的开始时间
                .withIssuedAt(clock.now())
                // 过期时间 1分钟
                .withExpiresAt(new Date(System.currentTimeMillis() + 10000))
                // 2小时
                //.setExpiration(new Date(System.currentTimeMillis() + expire))
                // 设置加密方式
                .sign(Algorithm.HMAC256(secret));

        return token;
    }

    /**
     * 认证 token
     *
     * @param token String
     * @return Boolean
     */
    public Boolean verifyToken(String token) {
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret)).build();
            DecodedJWT verify = verifier.verify(token);
            log.info("认证通过");
            log.info("loginName:{}", verify.getSubject());
            log.info("过去时间:{}", verify.getExpiresAt());
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException("登录凭证已经过期，请重新登录");
        }
    }


}
